<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        var c = console.log.bind(document)
        // 可选链:
        //     作用:检测可选链前的 行为 是否为null或undefined ,如果为 null或undefined就会停止执行返回undefined
        //     格式: 用?. 代替 . 操作符
        //     当有一个属性不确定是不是不存在 时,可选链可以更方便快捷的去识别

        // 判断obj.first下 是否有second 
        // 三元表达式写法:
        // let istrue = obj.first && obj.first.second
        // 先判断有没有 obj.first 是为了防止报错
        // 可选链写法
        // var obj = {
         
        // }
        // let option = obj.first.second // undefined 不可以接着执行下一步
        // let option = obj.first?.second // undefined 可以接着执行下一步
        // c(option)
        // let elapse = {
        //     1: {
        //         state: '未逾期',
        //         background: '#FFAD20'
        //     },
        //     2: {
        //         state: '即将逾期',
        //         background: '#FFAD20'
        //     },
        //     3: {
        //         state: '已逾期',
        //         background: '#eb5738'
        //     },
        //     4: {
        //         state: '逾期完成',
        //         background: '#f5d923'
        //     },
        //     5: {
        //         state: '未逾期完成',
        //         background: '#03be85'
        //     },
           
        // }
        // var taskDetails= {
        //     }
// 逻辑判断赋值法
// taskDetails.timeStatus == 1 或 2 或 10 10的时候就返回暂无
// sun = elapse && QUST.elapse[taskDetails.timeStatus] && QUST.elapse[taskDetails.timeStatus].state || "暂无";

// 可选链

// // 定义了 返回暂无
// sun = elapse?.[taskDetails?.timeStatus]?.state || "暂无";
// c(sun)

//  // 未定义 报错 date is not defined
// //  sun = elapse?.[date?.timeStatus]?.state || "暂无";
// c(date?.timeStatus)

// // 返回暂无
// sun = elapse?.[elapse.date?.timeStatus]?.state || "暂无";
// c(sun)


// var a = Number(elapse.date?.timeStatus)
// c(a)

// hasOwnProperty
// 作用: 检测数据有没有相对应的属性 (键/属性名)
// 格式: 要检测的数据.hasOwnProperty('属性名')
// var obj ={String:1}
// obj.hasOwnProperty1 = '1'
// c(obj.hasOwnProperty('hasOwnproPerty1'))
// c(obj.hasOwnProperty('String'))
// c(obj.hasOwnProperty('hasOwnproPerty2'))
// c(obj.hasOwnProperty('hasOwnproPerty3'))
// indexOf  
// zuoyong:根据索引查找对应的字符串

// object.assgin
// 作用: 将 所有可枚举的值从一个或多个源目标给到目标对象,返回目标对象
// 格式: object.assgin(目标对象,源目标,源目标)
    // var o1 = {a:1,b:2}
    // var o2 = {c:1,b:3}
    // var o3 = {c:3,d:2}
    // var o5 = {c:1,d:3}
    // // 如果目标对象里有和源目标相同的键时,
    // // 后面源目标的值会把目标对象的键覆盖掉
    // var o4 = Object.assign(o5,o1,o2,o3)
    // c(o1)   //  {a: 1, b: 2}
    // c(o2)   //  {c: 1, b: 3}
    // c(o3)   //  {c: 3, d: 2}
    // c(o4)   //  {c: 3, d: 2, a: 1, b: 3}
    // c(o5)   //  {c: 3, d: 2, a: 1, b: 3}

    // 复制一个对象
    // var o1 = {a:1,b:2}
    // // 将o1复制到o4
    // var o4 = {}
    // c(Object.assign(o4,o1)) // {a: 1, b: 2}
    // 合并对象
    // var o1 = {a:1,b:2}
    // var o2 = {c:1,b:3}
    // var o4 = {}
    // // 将o1,o2合并到o4
    // c(Object.assign(o4,o1,o2)) // {a: 1, b: 3, c: 1}

    // 合并具有相同属性的对象
    // var o1 = {a:1,b:2}
    // var o2 = 123
    // var o4 = Object.assign({},o1,o2)
    // c(o4);c(o1);c(o2)
    // o1.a=2;
    // c(o4);c(o1);c(o2)

    // Object.values
    // 作用: 返回对象中所有的可枚举属性值,使用方法和 for in 差不多
    // 注意:返回装载数据的数组,数据的顺序与遍历出来的数据顺序是一样的
    // var o1 = {a:1,b:2}
    // var o2 = {c:1,b:3}
    // var o3 = {2:{c:3,d:2}}
    // var o5 = {ad:[1,3]}
    // c(Object.values(o1))
    // c(Object.values(o2))
    // c(Object.values(o3))
    // c(Object.values(o5))    

    // 合并数组
    // const deps = {
    // '采购部':[1,2,3],
    // '人事部':[5,8,12],
    // '行政部':[5,14,79],
    // '运输部':[3,64,105],
    // }
    // let member = [];
    // // 先把deps 的数值全部遍历出来
    // for (let item in deps){
    //     // 定义一个变量接收deps 遍历的值
    //     const value = deps[item];
    //     // 判断 value 是不是一个数组
    //     if(Array.isArray(value)){
    //         // 把他们 用 ...(拓展运算符) 全部展开 最后给到 menber
    //         member = [...member,...value]
    //     }
    // }
    // // 过滤member 里的相同属性
    // member = [...new Set(member)]		
    // console.log(member)    // [1, 2, 3, 5, 8, 12, 14, 79, 64, 105]

 
    // 合并数组
    // const deps = {
    // '采购部':[1,2,3],
    // '人事部':[5,8,12],
    // '行政部':[5,14,79],
    // '运输部':[3,64,105],
    // }
    // var numbers = []
    // for(var item in deps) {
    //     var values=deps[item]
    //     if(Array.isArray(values)){
    //         numbers=[...numbers,...values]
    //     }
    // }
    // numbers=[... new Set(numbers)]
    // c(numbers)

    // const deps = {
    // '采购部':[1,2,3],
    // '人事部':[5,8,12],
    // '行政部':[5,14,79],
    // '运输部':[3,64,105],
    // }
    // // [... new Set] 去重
    // // Object.values(deps) 返回deps 自身所有可枚举的属性值
    // // .flat  把数组的值展开合并到一个数组里
    // let numbers = [... new Set(Object.values(deps).flat())]
    // c(numbers)

    // Object.keys[]
    // 作用:返回对象自身枚举的key值 (属性名)
    var obj = {1:'a',2:'b',3:'c'}
    var obj1 = {0:'a',1:'b',3:'c'}
    var obj2 = {1:'a',4:'b',3:'c'}
    var array = [1,2,3,4,4]
    c(Object.keys(obj))
    c(Object.keys(obj1))
    c(Object.keys(obj2))
    // c(Object.keys(array))
    // // 检测数据是否为空
    // c(Object.keys({}).length) // 输出0即为无数值
</script>    
</body>
</html>